package cn.js.sip.rat.system.service.impl;

import cn.js.sip.rat.system.entity.SysMenuEntity;
import cn.js.sip.rat.system.entity.SysRoleEntity;
import cn.js.sip.rat.system.entity.SysUserEntity;
import cn.js.sip.rat.system.entity.ZtreeEntity;
import cn.js.sip.rat.system.mapper.SysMenuMapper;
import cn.js.sip.rat.system.mapper.SysUserMapper;
import cn.js.sip.rat.system.service.SysLogService;
import cn.js.sip.rat.system.service.SysMenuService;
import cn.js.sip.rat.system.service.SysRoleService;
import cn.js.sip.rat.system.util.ShiroUtils;
import cn.js.sip.rat.system.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @ClassName: cn.js.sip.rat.system.service.impl
 * @Description: TODO
 * @author: xuxiaoli
 * @Date: 2019-12-28   17:07
 */
@Service("sysMenuService")
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuEntity> implements SysMenuService {
    private static Logger logger = LoggerFactory.getLogger(SysMenuServiceImpl.class);
    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource(name = "sysRoleService")
    private SysRoleService sysRoleService;

    @Override
    public void update(SysMenuEntity sysMenuEntity) {
        sysMenuMapper.updateById(sysMenuEntity);
        logger.info("menu update....");
        SysLogService.saveLog(sysMenuEntity.getId(), sysMenuEntity.getMenuCode(), sysMenuEntity.getMenuName(), "菜单", "更新");
    }

    @Override
    public void delete(String id) {
        logger.info("menu delete....");
        sysMenuMapper.deleteById(id);
    }

    @Override
    public List<SysMenuEntity> select(SysMenuEntity menuEntity) {
        logger.info("menu select....");
        return sysMenuMapper.getList();
    }

    @Override
    public List<SysMenuEntity> getMenusByUser(SysUserEntity userEntity) {
        if (userEntity.isAdmin()) {
            List<SysMenuEntity> allMenus = sysMenuMapper.getList();
            List<SysMenuEntity> firstMenus = firstMenu(allMenus);
            childMenu(allMenus, firstMenus);
            return firstMenus;
        }
        List<SysRoleEntity> sysRoleEntities = sysRoleService.getRolesByUserId(userEntity.getId());
        Set<SysMenuEntity> allMenus =new HashSet<>();
        sysRoleEntities.forEach(sysRoleEntity -> {
            List<SysMenuEntity> menus = sysMenuMapper.getMenusByRole(sysRoleEntity.getId());
            allMenus.addAll(menus);
        });
        ArrayList<SysMenuEntity> sysMenuEntities = new ArrayList<>(allMenus);
        List<SysMenuEntity> firstMenus = firstMenu(sysMenuEntities);
        childMenu(sysMenuEntities, firstMenus);
        return firstMenus;
    }

    @Override
    public List<SysMenuEntity> selectMenuList(SysMenuEntity menu, String userId) {
        List<SysMenuEntity> menuList = null;
        menuList = sysMenuMapper.selectMenuListByUserId(userId);
        return menuList;
    }

    @Override
    public SysMenuEntity selectMenuById(String id) {
        SysMenuEntity sysMenuDto = sysMenuMapper.selectMenuById(id);
        return sysMenuDto;
    }

    @Override
    public String checkMenuNameUnique(SysMenuEntity menu) {
        QueryWrapper<SysMenuEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(menu);
        SysMenuEntity sysMenuEntity = sysMenuMapper.selectOne(queryWrapper);
        if (Optional.ofNullable(sysMenuEntity).isPresent()) {
            return "1";
        }
        return "0";
    }

    @Override
    public List<ZtreeEntity> roleMenuTreeData(SysRoleEntity role, String userId) {
        String roleId = role.getId();
        List<ZtreeEntity> ztrees = new ArrayList<ZtreeEntity>();
        List<SysMenuEntity> menuList = selectMenuAll(userId);
        if (StringUtils.isNotNull(roleId)) {
            List<String> roleMenuList = sysMenuMapper.selectMenuTree(roleId);
            ztrees = initZtree(menuList, roleMenuList, true);
        } else {
            ztrees = initZtree(menuList, null, true);
        }
        return ztrees;
    }


    /**
     * 对象转菜单树
     *
     * @param menuList     菜单列表
     * @param roleMenuList 角色已存在菜单列表
     * @param permsFlag    是否需要显示权限标识
     * @return 树结构列表
     */
    public List<ZtreeEntity> initZtree(List<SysMenuEntity> menuList, List<String> roleMenuList, boolean permsFlag) {
        List<ZtreeEntity> ztrees = new ArrayList<ZtreeEntity>();
        boolean isCheck = StringUtils.isNotNull(roleMenuList);
        for (SysMenuEntity menu : menuList) {
            ZtreeEntity ztree = new ZtreeEntity();
            ztree.setId(menu.getId());
            ztree.setpId(menu.getParentId());
            ztree.setName(transMenuName(menu, permsFlag));
            ztree.setTitle(menu.getMenuName());
            if (isCheck) {
                ztree.setChecked(roleMenuList.contains(menu.getId() + menu.getPerms()));
            }
            ztrees.add(ztree);
        }
        return ztrees;
    }

    public String transMenuName(SysMenuEntity menu, boolean permsFlag) {
        StringBuffer sb = new StringBuffer();
        sb.append(menu.getMenuName());
        if (permsFlag) {
            sb.append("<font color=\"#888\">&nbsp;&nbsp;&nbsp;" + menu.getPerms() + "</font>");
        }
        return sb.toString();
    }
    /**
     * 查询菜单集合
     *
     * @return 所有菜单信息
     */
    @Override
    public List<SysMenuEntity> selectMenuAll(String userId) {
        SysUserEntity userEntity = sysUserMapper.selectById(userId);
        List<SysMenuEntity> menuList = null;
        if (userEntity.isAdmin()) {
            menuList = sysMenuMapper.getList();
        } else {
            menuList = sysMenuMapper.selectMenuListByUserId(userId);
        }
        return menuList;
    }

    protected List<SysMenuEntity> firstMenu(List<SysMenuEntity> menus) {
        List<SysMenuEntity> firstMenus = new LinkedList<>();
        menus.forEach(menuDto -> {
            if (menuDto.firstMenued()) {
                firstMenus.add(menuDto);
            }
        });
        return firstMenus;
    }

    protected List<SysMenuEntity> childMenu(List<SysMenuEntity> menus, List<SysMenuEntity> parentMenus) {

        parentMenus.forEach(parentMenu -> {
            List<SysMenuEntity> childMenus = new ArrayList<>();
            menus.forEach(menu -> {
                if (menu.getParentId() != null && parentMenu.getId().equals(menu.getParentId())) {
                    childMenus.add(menu);
                }
            });
            parentMenu.setChildren(childMenus);
        });

        return parentMenus;
    }

    @Override
    public void save(SysMenuEntity menuEntity) {
        menuEntity.setCreateInfo();
        menuEntity.setCreaterId(ShiroUtils.getSysUser().getId());
        sysMenuMapper.insert(menuEntity);
    }
}
